home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / pmake / customs / os-bsd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-11-15  |  10.0 KB  |  351 lines

  1. /***********************************************************************
  2.  *
  3.  * PROJECT:      PMake
  4.  * MODULE:      Customs -- BSD UNIX dependencies
  5.  * FILE:      os-bsd.c
  6.  *
  7.  * AUTHOR:        Adam de Boor: Sep  9, 1989
  8.  *
  9.  * ROUTINES:
  10.  *    Name              Description
  11.  *    ----              -----------
  12.  *    OS_Init                Initialize module and return mask of criteria
  13.  *                        to be considered in determination.
  14.  *    OS_Idle                Return machine idle time, in seconds
  15.  *    OS_Load                Return machine load factor
  16.  *    OS_Swap                Return free swap space
  17.  *
  18.  * REVISION HISTORY:
  19.  *    Date      Name        Description
  20.  *    ----      ----        -----------
  21.  *    9/ 9/89      ardeb        Initial version
  22.  *
  23.  * DESCRIPTION:
  24.  *    OS-dependent functions for BSD-related systems. This includes:
  25.  *        SunOS 3.x
  26.  *        Ultrix
  27.  *        BSD 4.2 and 4.3
  28.  *
  29.  *    These functions are responsible for the determination of the
  30.  *    current state of the system, returning it as a set of numbers
  31.  *    in a customs-standard form, whatever form they may be in in the
  32.  *    system itself.
  33.  *
  34.  *    The format used is the same as that transmitted for the AVAIL_SET
  35.  *    RPC.
  36.  *
  37.  *     Copyright (c) Berkeley Softworks 1989
  38.  *     Copyright (c) Adam de Boor 1989
  39.  *
  40.  *     Permission to use, copy, modify, and distribute this
  41.  *     software and its documentation for any non-commercial purpose
  42.  *    and without fee is hereby granted, provided that the above copyright
  43.  *     notice appears in all copies.  Neither Berkeley Softworks nor
  44.  *     Adam de Boor makes any representations about the suitability of this
  45.  *     software for any purpose.  It is provided "as is" without
  46.  *     express or implied warranty.
  47.  *
  48.  *
  49.  ***********************************************************************/
  50. #ifndef lint
  51. static char *rcsid =
  52. "$Id: os-bsd.c,v 1.1 89/09/11 11:07:20 adam Exp $";
  53. #endif lint
  54.  
  55. #include    "customsInt.h"
  56.  
  57. #undef NULL
  58.  
  59. #include    <sys/param.h>
  60. #include    <sys/stat.h>
  61. #include    <sys/conf.h>
  62. #include    <sys/map.h>
  63. #include    <nlist.h>
  64. #include    <sys/file.h>
  65. /*#include    <sys/time.h>*/
  66. #include    <stdio.h>
  67.  
  68. #ifndef mapstart
  69. /*
  70.  * Apparently, Ultrix doesn't have these macros...
  71.  */
  72. #define mapstart(X)    (struct mapent *)((X)+1)
  73. #define mapfree(X)    (X)->m_free
  74. #define mapwant(X)    (X)->m_want
  75. #define mapname(X)    ((struct maplast *)(X))->m_nam
  76. #endif /* mapstart */
  77.  
  78. static struct nlist kAddrs[] = {
  79. {    "_nswapmap"    },       /* Number of swap resource maps */
  80. #define NSWAPMAP      0
  81. {    "_nswdev"     },       /* Number of swap devices       */
  82. #define NSWDEV          1
  83. {    "_swapmap"    },       /* The swap resource maps       */
  84. #define SWAPMAP          2
  85. {    "_swdevt"     },       /* The swap devices             */
  86. #define SWDEVT          3
  87. {    "_avenrun"    },       /* Load averages                */
  88. #define AVENRUN          4
  89. {    ""            }
  90. };
  91.  
  92. static int            kmem;            /* Descriptor to /dev/kmem */
  93. static int            kbd;            /* Descriptor to /dev/kbd */
  94.  
  95. /*
  96.  * The existence of the constant FSCALE is used to determine in what format
  97.  * the system's load average is stored. If FSCALE is defined, it indicates
  98.  * a 32-bit fixed-point number is being used. The number is divided by
  99.  * FSCALE using floating point arithmetic to obtain the actual load
  100.  * average.
  101.  *
  102.  * If FSCALE isn't defined (standard BSD), the calculations are performed using
  103.  * double floating point math.
  104.  */
  105. #ifdef FSCALE
  106. static long           avenrun[3];    /* Load averages */
  107. #else
  108. static double        avenrun[3];    /* Load averages */
  109. #endif /* FSCALE */
  110.  
  111. static int            swblocks;     /* Total swap space available */
  112. static int            nSwapMap;     /* Number of entries in the swap map */
  113. static off_t          swapMapAddr;    /* Address in sysspace of the map */
  114. static struct map     *swapMap;     /* Space for swap map */
  115. static int            swapMapSize;    /* Size of the swap map (bytes) */
  116.  
  117.  
  118.  
  119. /***********************************************************************
  120.  *                OS_Init
  121.  ***********************************************************************
  122.  * SYNOPSIS:        Initialize this module
  123.  * CALLED BY:        Avail_Init
  124.  * RETURN:        Mask of AVAIL_* bits indicating what criteria are
  125.  *                to be examined.
  126.  * SIDE EFFECTS:
  127.  *
  128.  * STRATEGY:
  129.  *
  130.  * REVISION HISTORY:
  131.  *    Name    Date        Description
  132.  *    ----    ----        -----------
  133.  *    ardeb    9/ 9/89        Initial Revision
  134.  *
  135.  ***********************************************************************/
  136. int
  137. OS_Init()
  138. {
  139.     struct swdevt   *swapDevices,
  140.             *sw;
  141.     int                numSwapDevices;
  142.     int                retMask;
  143.  
  144.     /*
  145.      * Default to everything.
  146.      */
  147.     retMask = AVAIL_EVERYTHING;
  148.  
  149.     /*
  150.      * Extract the addresses for the various data structures that we examine.
  151.      * XXX: Perhaps this thing should allow some other name than /vmunix?
  152.      */
  153.     if (nlist ("/vmunix", kAddrs) < 0) {
  154.     printf ("/vmunix: could not read symbol table\n");
  155.     exit(1);
  156.     }
  157.     /*
  158.      * Open a stream to the kernel's memory so we can actually look at the
  159.      * data structures.
  160.      */
  161.     if ((kmem = open ("/dev/kmem", O_RDONLY, 0)) < 0) {
  162.     printf ("Could not open /dev/kmem\n");
  163.     exit(1);
  164.     }
  165. #ifdef sun
  166.     /*
  167.      * Try for a keyboard device. It's ok if we can't open this thing. It
  168.      * just means we're not on a workstation and so can't determine idle time.
  169.      */
  170.     if ((kbd = open ("/dev/kbd", O_RDONLY, 0)) < 0) {
  171.     /*
  172.      * If couldn't open keyboard, we can't tell how long the machine's
  173.      * been idle.
  174.      */
  175.     retMask &= ~AVAIL_IDLE;
  176.     }
  177. #else
  178.     retMask &= ~AVAIL_IDLE;
  179. #endif
  180.  
  181.     /*
  182.      * Find the total number of swap blocks available to the machine
  183.      * by summing the amounts in the swdevt descriptors
  184.      */
  185.     lseek (kmem, (off_t)kAddrs[NSWDEV].n_value, L_SET);
  186.     read (kmem, (char *)&numSwapDevices, sizeof (numSwapDevices));
  187.  
  188.     swapDevices =
  189.     (struct swdevt *)malloc (numSwapDevices * sizeof (struct swdevt));
  190.  
  191.     lseek (kmem, (off_t)kAddrs[SWDEVT].n_value, L_SET);
  192.     read (kmem, (char *)swapDevices, numSwapDevices*sizeof(struct swdevt));
  193.  
  194.     for (swblocks=0, sw=swapDevices; numSwapDevices!=0; sw++, numSwapDevices--)
  195.     {
  196.     if (sw->sw_freed) {
  197.         swblocks += sw->sw_nblks;
  198.     }
  199.     }
  200.     free ((Address) swapDevices);
  201.  
  202.     /*
  203.      * Find and save the number and location of the swap maps for
  204.      * the local machine, then allocate enough room to hold them
  205.      * all, pointing 'swapMap' to the space.
  206.      */
  207.     lseek (kmem, (off_t) kAddrs[NSWAPMAP].n_value, L_SET);
  208.     read (kmem, (char *)&nSwapMap, sizeof (nSwapMap));
  209.     lseek (kmem, (off_t) kAddrs[SWAPMAP].n_value, L_SET);
  210.     read (kmem, (char *)&swapMapAddr, sizeof(swapMapAddr));
  211.     
  212.     printf ("%d swap blocks total allocated among %d maps at 0x%08x\n",
  213.         swblocks, nSwapMap, swapMapAddr);
  214.     swapMapSize = nSwapMap * sizeof (struct map);
  215.  
  216.     swapMap = (struct map *) malloc (swapMapSize);
  217.  
  218.     return(retMask);
  219. }
  220.  
  221.  
  222. /***********************************************************************
  223.  *                OS_Idle
  224.  ***********************************************************************
  225.  * SYNOPSIS:        Find the idle time of the machine
  226.  * CALLED BY:        Avail_Local
  227.  * RETURN:        The number of seconds for which the machine has been
  228.  *                idle.
  229.  * SIDE EFFECTS:    None
  230.  *
  231.  * STRATEGY:
  232.  *    Locate the access time for the keyboard device and subtract it
  233.  *    from the current time to obtain the number of seconds the
  234.  *    keyboard has been idle. The assumption is that the keyboard
  235.  *    device's idle time reflects that of the machine. This does not
  236.  *    take into account rlogin connections, or non-Sun systems that
  237.  *    are workstations but don't have a keyboard device.
  238.  *
  239.  *
  240.  * REVISION HISTORY:
  241.  *    Name    Date        Description
  242.  *    ----    ----        -----------
  243.  *    ardeb    9/10/89        Initial Revision
  244.  *
  245.  ***********************************************************************/
  246. int
  247. OS_Idle()
  248. {
  249.     struct stat        kbStat;
  250.     struct timeval  now;
  251.  
  252.     fstat (kbd, &kbStat);
  253.     gettimeofday (&now, (struct timezone *)0);
  254.     
  255.     return (now.tv_sec - kbStat.st_atime);
  256. }
  257.  
  258.  
  259. /***********************************************************************
  260.  *                OS_Swap
  261.  ***********************************************************************
  262.  * SYNOPSIS:        Find the percentage of the system's swap space that
  263.  *                isn't being used.
  264.  * CALLED BY:        Avail_Local
  265.  * RETURN:        The percentage of free swap space
  266.  * SIDE EFFECTS:    None
  267.  *
  268.  * STRATEGY:
  269.  *    The number of free blocks is simple the number of blocks described
  270.  *    by the system's swap maps, whose address we've got in swapMapAddr.
  271.  *
  272.  * REVISION HISTORY:
  273.  *    Name    Date        Description
  274.  *    ----    ----        -----------
  275.  *    ardeb    9/10/89        Initial Revision
  276.  *
  277.  ***********************************************************************/
  278. int
  279. OS_Swap()
  280. {
  281.     int                free;        /* Number of free blocks so far */
  282.     struct mapent    *mapEnd;    /* End of swap maps */
  283.     struct mapent    *mapEntry;    /* Current map */
  284.     
  285.     lseek (kmem, swapMapAddr, L_SET);
  286.     read (kmem, (char *)swapMap, swapMapSize);
  287.     
  288.     mapEnd = (struct mapent *) &swapMap[nSwapMap];
  289.     free = 0;
  290.     for (mapEntry = mapstart(swapMap); mapEntry < mapEnd; mapEntry++) {
  291.     free += mapEntry->m_size;
  292.     }
  293.     return ((free * 100) / swblocks);
  294. }
  295.  
  296.  
  297. /***********************************************************************
  298.  *                OS_Load
  299.  ***********************************************************************
  300.  * SYNOPSIS:        Return the current load average in standard form
  301.  * CALLED BY:        Avail_Local
  302.  * RETURN:        The current load as a 32-bit fixed-point number
  303.  * SIDE EFFECTS:    None
  304.  *
  305.  * STRATEGY:
  306.  *
  307.  * REVISION HISTORY:
  308.  *    Name    Date        Description
  309.  *    ----    ----        -----------
  310.  *    ardeb    9/10/89        Initial Revision
  311.  *
  312.  ***********************************************************************/
  313. unsigned long
  314. OS_Load()
  315. {
  316.     unsigned long   result;
  317.  
  318.     lseek (kmem, (off_t) kAddrs[AVENRUN].n_value, L_SET);
  319.     read (kmem, (char *)avenrun, sizeof (avenrun));
  320.     
  321. #ifdef FSCALE
  322. #define CVT(v)    ((double)(v)/FSCALE)*LOADSCALE
  323. #else
  324. #define CVT(v)    ((v) * LOADSCALE)
  325. #endif /* FSCALE */
  326.  
  327. #ifdef ALL_LOAD
  328.     /*
  329.      * Find largest of the three averages and return that
  330.      */
  331.     if (avenrun[0] > avenrun[1]) {
  332.     if (avenrun[0] > avenrun[2]) {
  333.         result = CVT(avenrun[0]);
  334.     } else {
  335.         result = CVT(avenrun[2]);
  336.     }
  337.     } else if (avenrun[1] > avenrun[2]) {
  338.     result = CVT(avenrun[1]);
  339.     } else {
  340.     result = CVT(avenrun[2]);
  341.     }
  342. #else
  343.     /*
  344.      * Just return the 1-minute average.
  345.      */
  346.     result = CVT(avenrun[0]);
  347. #endif
  348.  
  349.     return(result);
  350. }
  351.